
/**
 * 
 */
package co.fitstart.data.web.resolver;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.util.WebUtils;

import co.fitstart.data.Constant;
import co.fitstart.data.security.AuthenticationProvider;
import co.fitstart.entity.user.User;

/**
 * @author lute
 *
 */
public class SecurityArgumentResolver implements HandlerMethodArgumentResolver {

    private static final Logger logger = LoggerFactory.getLogger(SecurityArgumentResolver.class);
    
    private String mobileKey = Constant.MOBILE_KEY;
    
    @Autowired
    private AuthenticationProvider authenticationProvider;
    
    /**
     * 
     * @param mobileKey
     */
    public void setMobileKey(String mobileKey) {
        this.mobileKey = mobileKey;
    }
    
    /* (non-Javadoc)
     * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
     */
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Secure.class);
    }

    /* (non-Javadoc)
     * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.method.support.ModelAndViewContainer, org.springframework.web.context.request.NativeWebRequest, org.springframework.web.bind.support.WebDataBinderFactory)
     */
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        
        Secure secure = parameter.getParameterAnnotation(Secure.class);
        
        if (StringUtils.isNotBlank(secure.value())) {
            this.mobileKey = secure.value();
        }
        
    	logger.trace("WechatSecurityArgumentResovler#resolveArgument() - Get mobile key [{}].", mobileKey);
        
        // Transform NativeWebRequest to HttpServletRequest
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        
        // Get openid cookie
        Cookie mobileCookie = WebUtils.getCookie(request, mobileKey);
        
        logger.trace("WechatSecurityArgumentResovler#resolveArgument() - Get mobile cookie by mobileKey [{}].", mobileKey);
        
        if (mobileCookie != null) {
            
            String mobile = mobileCookie.getValue();
            
            logger.trace("WechatSecurityArgumentResovler#resolveArgument() - Get mobile cookie success ======== MOBILE COOKIE VALUE IS [{}].", mobile);
            
            // Load user
            User user = authenticationProvider.loadUser(mobile);
            
            // Return user when there's no property in secure annotation
            if (user != null && parameter.getParameterType().isAssignableFrom(user.getClass())) {
                logger.trace("WechatSecurityArgumentResovler#resolveArgument() - Load user by mobile [{}] and user id is [{}].", mobile, user.getId());
                return user;
            }
            
            logger.trace("WechatSecurityArgumentResovler#resolveArgument() - Load user by mobile [{}] failed.", mobile);
            
        }else {
            
            logger.trace("WechatSecurityArgumentResovler#resolveArgument() - Get mobile cookie failed ======== MOBILE COOKIE NOT EXIT.");
        }
        
        
        return null;
    }

}
